package com.superman.supermarket.client.composite.cart.bottom;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Widget;
import com.superman.mvpframe.client.gin.XGinjector;
import com.superman.mvpframe.client.utils.MathUtil;
import com.superman.supermarket.client.composite.IUIListModule;
import com.superman.supermarket.client.constant.CartSkuOperateConstants;
import com.superman.supermarket.client.event.CartPageEvent;
import com.superman.supermarket.client.event.CartPageEvent.CartPageEventType;
import com.superman.supermarket.client.widget.button.CheckButton;

/**
 * 购物车底部模块
 * 
 * @author superman
 * @version 2018年8月9日上午10:53:55
 */
public class CartBottomModule extends Composite implements IUIListModule {

	interface CartBottomModuleUiBinder extends UiBinder<Widget, CartBottomModule> {
	}

	private static CartBottomModuleUiBinder uiBinder = GWT.create(CartBottomModuleUiBinder.class);

	private HandlerRegistration cartEventHR;
	@UiField
	CheckButton checkbtn;
	private List<Map<String, Object>> originalStoreList;

	private List<String> selectedTempStoreList = new ArrayList<String>();
	private List<Map<String, Object>> skuList = new ArrayList<Map<String, Object>>();

	@UiField
	Button submitbtn;

	@UiField
	HTML totalfeehtml;
	private String totalNumStr = "0";

	private String totalPriceStr = "0";

	/**
	 * 构造方法
	 * 
	 * @author superman
	 * @version 2018年8月9日 上午10:53:57
	 */
	public CartBottomModule() {
		initWidget(uiBinder.createAndBindUi(this));
	}

	private void addSkuAndUpdataTotalPrice(Map<String, Object> skuMap, AsyncCallback<String> priceCallback,
			AsyncCallback<String> numCallback) {
		skuList.add(skuMap);
		totalPriceStr = MathUtil.add(totalPriceStr, calSkuPrice(skuMap));
		totalNumStr = MathUtil.add(totalNumStr, String.valueOf(skuMap.get("SKU_NUM")));
		priceCallback.onSuccess(totalPriceStr);
		numCallback.onSuccess(totalNumStr);
	}

	private String calSkuPrice(Map<String, Object> skuMap) {
		String num = String.valueOf(skuMap.get("SKU_NUM"));
		String price = String.valueOf(skuMap.get("SALE_PRICE"));

		return MathUtil.mul(num, price);
	}

	@UiHandler("checkbtn")
	void checkAll(ClickEvent event) {

		if (!checkbtn.isCheck()) {
			selectedTempStoreList.clear();
			skuList.clear();
		}

		CartPageEvent cartPageEvent = new CartPageEvent(CartPageEventType.CHEACK_ALL, checkbtn.isCheck());
		XGinjector.INSTANCE.getEventbusController().fire(cartPageEvent);

	}

	@Override
	public List<Map<String, Object>> getListData() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void onAttach() {
		super.onAttach();
		cartEventHR = XGinjector.INSTANCE.getEventbusController().addHandler(CartPageEvent.TYPE, new CartPageEvent.CartPageEventHandler() {

			@Override
			public void checkAll(boolean check) {
				// 不做处理
			}

			@Override
			public void checkSku(Map<String, Object> map) {
				// 不做处理
			}

			@Override
			public void checkStore(String storeId) {
				// 需要处理
				if (selectedTempStoreList.indexOf(storeId) == -1) {
					selectedTempStoreList.add(storeId);
					checkbtn.setCheck(originalStoreList.size() == selectedTempStoreList.size());
				}

			}

			@Override
			public void delete(String skuId) {
				// 不做处理
			}

			@Override
			public void settlement() {
				// TODO Auto-generated method stub

			}

			@Override
			public void unCheckSku(Map<String, Object> map) {
				// 不做处理
			}

			@Override
			public void uncheckStore(String storeId) {
				// 需要处理
				if (selectedTempStoreList.indexOf(storeId) > -1) {
					selectedTempStoreList.remove(storeId);
					checkbtn.setCheck(originalStoreList.size() == selectedTempStoreList.size());
				}

			}

			@Override
			public void updatePrice(Map<String, Object> map) {
				updateTotalPrice(map, new AsyncCallback<String>() {

					@Override
					public void onFailure(Throwable caught) {

					}

					@Override
					public void onSuccess(String result) {
						totalfeehtml.setText(result);
					}
				}, new AsyncCallback<String>() {

					@Override
					public void onFailure(Throwable caught) {

					}

					@Override
					public void onSuccess(String result) {
						int num = (int) Double.parseDouble(result);
						updateSubmitBtn(num);
					}
				});
			}

		});
	}

	@Override
	protected void onDetach() {
		super.onDetach();
		cartEventHR.removeHandler();
	}

	/**
	 * 重制
	 * 
	 * @author superman
	 * @version 2018年8月22日 下午10:08:00
	 */
	public void reset() {
		totalNumStr = "0";
		totalPriceStr = "0";
		if (originalStoreList != null)
			originalStoreList.clear();
		selectedTempStoreList.clear();
		skuList.clear();
		totalfeehtml.setText("");
		checkbtn.setCheck(false);
		updateSubmitBtn(0);
	}

	@Override
	public void setListData(List<Map<String, Object>> list) {
		this.originalStoreList = list;
	}

	@UiHandler("submitbtn")
	void settlement(ClickEvent event) {
		XGinjector.INSTANCE.getEventbusController().fire(new CartPageEvent(CartPageEventType.SETTLEMENT));
	}

	private void subSkuAndUpdataTotalPrice(Map<String, Object> skuMap, AsyncCallback<String> priceCallback,
			AsyncCallback<String> numCallback) {
		skuList.remove(skuMap);
		totalPriceStr = MathUtil.sub(totalPriceStr, calSkuPrice(skuMap));
		totalNumStr = MathUtil.sub(totalNumStr, String.valueOf(skuMap.get("SKU_NUM")));
		priceCallback.onSuccess(totalPriceStr);
		numCallback.onSuccess(totalNumStr);
	}

	private void updateSkuNumAndUpdataTotalPrice(Map<String, Object> skuMap, AsyncCallback<String> priceCallback,
			AsyncCallback<String> numCallback) {
		boolean contain = false;
		for (Map<String, Object> map : skuList) {
			if (String.valueOf(map.get("SKU_ID")).equals(skuMap.get("SKU_ID"))) {
				contain = true;
				subSkuAndUpdataTotalPrice(map, priceCallback, numCallback);
				break;
			}
		}
		if (contain)
			addSkuAndUpdataTotalPrice(skuMap, priceCallback, numCallback);
	}

	private void updateSubmitBtn(int num) {
		if (num == 0) {
			submitbtn.setEnabled(false);
			submitbtn.setText("结算");
			submitbtn.removeStyleName("base-bg-color");
			submitbtn.addStyleName("invalid-bg-color");
		} else {

			submitbtn.setEnabled(true);
			submitbtn.setText("结算(" + num + ")");
			submitbtn.removeStyleName("invalid-bg-color");
			submitbtn.addStyleName("base-bg-color");

		}
	}

	/**
	 * 计算价格
	 * 
	 * @author superman
	 * @version 2018年8月10日 下午9:26:12
	 * @param skuMap
	 * @param priceCallback
	 * @param numCallback
	 */
	public void updateTotalPrice(Map<String, Object> skuMap, AsyncCallback<String> priceCallback, AsyncCallback<String> numCallback) {

		CartSkuOperateConstants type = CartSkuOperateConstants.valueOf(String.valueOf(skuMap.get("TYPE")));
		// 这里的type要移除,要移除!
		// 不然skulist里面的map传入都带类型,add和sub即使是同一个sku,map内容也一样,会导致add的时候和remove的时候 不是同一个map,切记
		skuMap.remove("TYPE");
		switch (type) {
			case ADD_SKU:
				addSkuAndUpdataTotalPrice(skuMap, priceCallback, numCallback);
				break;
			case SUB_SKU:
				subSkuAndUpdataTotalPrice(skuMap, priceCallback, numCallback);
				break;
			case UPDATE_NUM:
				updateSkuNumAndUpdataTotalPrice(skuMap, priceCallback, numCallback);
				break;
			default:
				break;
		}

	}

}
